class Heart{
  mySocket=null;
  //0啥也没做
  //1 发送了ping信号
  //2 发送了pong信号
  flag=0;
  //ping和pong的定时器
  pingTimer=null;
  pongTimer=null;

  constructor(mySocket){
    this.mySocket=mySocket;
  }

  //接受pong信号，改变标识状态，如果标识不正确，停止心跳 重新连接


  getPong=(e)=>{
    if(e.data==='pong'){
      if(this.flag===1){
        this.flag=2;
      }else{
        //出现问题
        this.stop();
      }
    }
  };
  //开始心跳监测
start(){
  //绑定消息监听，接收pong信号
  this.mySocket.ws.addEventListener('message',this.getPong);
  //准备发送ping信号
  this.startPing();
}


//开始向服务器发送ping消息
startPing(){
  //启动定时器发送ping消息
  this.pingTimer=setTimeout(()=>{
    if(this.flag===0){
      this.flag=1;
      console.log('发送心跳检查消息');
      this.mySocket.ws.send('ping');
    }else{
      //出现问题
      this.stop();
      this.mySocket.init();
      return
    }
    //规定时间内接收服务器返回pong信号，才能确定连接没有问题
    this.pongTimer=setTimeout(()=>{
      //如果pong已经到位了，再次启动一个新的跳转
      if(this.flag===2){
        this.flag=0;
        this.startPing();
      }else{
        //否则出现问题，停止心跳检查
        this.stop();
        this.mySocket.init();
      }
    },2000)
  },50000)
}
//停止心跳检查
stop(){
  //重置flag
  this.flag=0;
  clearTimeout(this.pingTimer);
  clearTimeout(this.pongTimer);
  //移出接收消息的监听
  this.mySocket.ws.removeEventListener('message',this.getPong);
  //判断socket连接
  this.mySocket.ws.close();
}
};



class MySocket{
  //socket对象
  ws=null;
  //心跳监测对象
  heart=null;
  //重连次数
  repeatCount=0;
  //最大重连次数
  maxRepeatCount=3;
  //重连的定时器
  timer=null;
  //接收消息的回调函数（由组件指定）
  cb=null;
  lockRepeat=false;

  constructor(cb){
    this.cb=cb;
    this.init();
  };


  //创建webSocket连接，并绑定连接成功和失败的监听
  init(){
    this.ws=new WebSocket('ws://localhost:8080');
    this.ws.onopen=()=>{
      this.openHandler();
    };
    this.ws.onclose=()=>{
      this.closeHandler();
    }
  };


  //连接成功的回调

  openHandler(){
    //绑定接收消息的监听(用于组件接收列表数据)
    this.ws.addEventListener('message',this.cb);
    clearInterval(this.timer);
    this.repeatCount=0;
    //创建并启动心跳检查对象
    this.heart=new Heart(this);
    this.heart.start();
  }


  //连接失败的回调

  closeHandler(){
    if(this.lockRepeat)return
    this.lockRepeat=true;
    //连接数量加
    this.repeatCount++;
    //移出消息监听
    this.ws.removeEventListener('message',this.cb);
    //关闭心跳监测
    this.heart.stop();
    clearTimeout(this.timer);
    //如果连接次数大于了最大值
    if(this.repeatCount>this.maxRepeatCount){
      //提示错误，并结束
      alert('连接ws失败,请稍后再试');
      return
    }
    console.log('重连',this.repeatCount);
    //1秒后再重新连接
    this.timer=setTimeout(()=>{
      this.lockRepeat=false;
      this.init();
    },1000)
  }

}


export default MySocket
